package cn.sinjet.model.carsystem;

import com.mgroup.wazehelper.R;

import android.content.Context;
import android.util.Log;
import cn.sinjet.communication.bluetooth.BluetoothModel;
import cn.sinjet.model.carassist.AppModel;
import cn.sinjet.utils.SharedPreferenceUtil;
import cn.sinjet.viewmodel.OnMyDlgActionListener;
import cn.sinjet.viewmodel.PageDefine;
import cn.sinjet.viewmodel.ViewDefine;
import cn.sinjet.viewmodel.ViewEvent;
import cn.sinjet.viewmodel.ViewModel;

public class ControlModule {
   static String tag = "car";
   private static ControlModule instance = null;
   private static final int CMD_POWER = 0x01;
   private static final int CMD_WINDOWS = 0x02;
   private static final int CMD_LOCK = 0x03;
   private static final int CMD_SKYLIGHT = 0x04;
   private static final int CMD_TRUNK = 0x05;
   
   private static final int ON = 1;
   private static final int OFF = 0;
   Context mContext;
   int mControllingItem = -1;
   boolean mIsSettingPassword = false;
   boolean mIsVerifySucceed = false;
   String mPassword = "";
   boolean mIsCarControlSupport = false;
//   boolean mIsCarControlSupport = true;
   CarModel modules;
   
   public ControlModule(CarModel modules){
	   this.modules = modules;
   }
   
   /*public static ControlModule getInstance(){
	   if(instance == null) instance = new ControlModule();
	   return instance;
   }*/
   
   public void init(Context context){
	   mContext = context;
	   ViewModel.getIns().setViewProperty(R.id.car_window_close, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_window_close, "一键升窗");
	   ViewModel.getIns().setViewProperty(R.id.car_window_open, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_window_open, "一键降窗");
	   ViewModel.getIns().setViewProperty(R.id.car_lock, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_lock, "车门上锁");
	   ViewModel.getIns().setViewProperty(R.id.car_unlock, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_unlock, "车门解锁");
	   ViewModel.getIns().setViewProperty(R.id.car_trunk_open, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_trunk_open, "打开尾箱");
	   ViewModel.getIns().setViewProperty(R.id.car_power_on, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_power_on, "一键启动");
	   ViewModel.getIns().setViewProperty(R.id.car_power_off, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_power_off, "一键熄火");
	   ViewModel.getIns().setViewProperty(R.id.car_skylight_open, 0);
	   ViewModel.getIns().setViewProperty(R.id.car_skylight_open, "打开天窗");
   }
   public void uninit(){
	   
   }
   
   public boolean isCarControlSupport(){
	   return mIsCarControlSupport;
   }
   
   
   public void onCarModel(int flag){
	   Log.d(tag, "onCarModel ==============="+flag);
	   if(flag == 4){
		   ViewModel.getIns().setViewProperty(R.id.car_window_close, 1);
		   ViewModel.getIns().setViewProperty(R.id.car_window_open, 1);
	   }else if(flag == 3){
		   ViewModel.getIns().setViewVisible(R.id.setting_hud, 1);
//		   ViewModel.getIns().setViewVisible(R.id.setting_hud_screen, 1);
	   }
   }
   
   public void onViewEvent(ViewEvent event){
	   Log.i("view", "onViewEvent:"+event.getTag());
//	   showPasswordPannel();
	   int id = event.getTag();
	   switch(id){
	   case R.id.setting_hud:
		   onClkEnterSetHUD();
		   break;
	   case R.id.setting_hud_screen:
		   onClkEnterSetHUDScreen();
		   break;
		case R.id.hud_set_back:
			onClkHudSetBack();
			break;
		case R.id.gesture_down:
			onClkFlingDn();
			break;
		case R.id.gesture_up:
			onClkFlingUp();
			break;
		case R.id.gesture_ok:
			onClkOK();
			break;
	   case R.layout.layout_password_dialog:{
		   String password = event.getString();
		   onPasswordEnter(password);
	     }break;
	   case R.id.reset_control_psw:
		   onClkResetControlPsw();
	     break;
	   case R.id.car_window_close:
	   case R.id.car_window_open:
	   case R.id.car_trunk_open:
	   case R.id.car_lock:
	   case R.id.car_unlock:
	   case R.id.car_power_off:
	   case R.id.car_power_on:
	   case R.id.car_skylight_open:
		   mControllingItem = id;
		   ViewModel.getIns().refreshView(R.layout.layout_password_dialog);
	       break;
	   case R.id.hud_set_inc:
		   onTouchHudSetInc(event);
		   break;
	   case R.id.hud_set_dec:
		   onTouchHudSetDec(event);
		   break;
	   case R.id.hud_set_ok:
		   onTouchHudSetOK(event);
		   break;
	   }
  }
   
   int mIncState=0; int mDecState = 0; int mOkState = 0;
   
   void onTouchHudSetInc(ViewEvent event){
	   Log.d(tag, "inc:"+event.getAction());
	   mIncState =  (event.getAction()==ViewEvent.ACTION_DN)?1:0;
	   makeHUDSetMsgAndSend();
   }
   void onTouchHudSetDec(ViewEvent event){
	   Log.d(tag, "dec:"+event.getAction());
	   mDecState =  (event.getAction()==ViewEvent.ACTION_DN)?1:0;
	   makeHUDSetMsgAndSend();
   }
   void onTouchHudSetOK(ViewEvent event){
	   Log.d(tag, "ok:"+event.getAction());
	   mOkState =  (event.getAction()==ViewEvent.ACTION_DN)?1:0;
	   makeHUDSetMsgAndSend();
   }
   void onClkFlingDn(){
	   Log.d(tag, "onClkFlingDn");
	   mDecState = 2;
	   makeHUDSetMsgAndSend();
	   mDecState = 0;
   }
   void onClkFlingUp(){
	   Log.d(tag, "onClkFlingUp");
	   mIncState = 2;
	   makeHUDSetMsgAndSend();
	   mIncState = 0;
   }
   void onClkOK(){
	   Log.d(tag, "onClkOK");
	   mOkState = 2;
	   makeHUDSetMsgAndSend();
	   mOkState = 0;
   }
   
   void makeHUDSetMsgAndSend(){
	   Log.d(tag, "send button +:"+mIncState+" -:"+mDecState+" ok:"+mOkState);
	   byte[] buf = new byte[]{0x00,(byte)mIncState,(byte)mDecState,(byte)mOkState};
	   packHudMsgAndSend(buf, buf.length);
   }
   
   void onClkHudSetBack(){
	   ViewModel.getIns().jumpPageInUIThread(PageDefine.PAGE_SETTING_GENERAL);
//	   sendLeaveHudSet();
   }
   private void onClkEnterSetHUD(){
	   Log.d(tag, "onClkEnterSetHUD");
//	   sendEnterHudSet();
	   ViewModel.getIns().jumpPageInUIThread(PageDefine.PAGE_HUD_SET);
   }
   private void  onClkEnterSetHUDScreen(){
	   Log.d(tag, "onClkEnterSetHUDScreen");
	   ViewModel.getIns().jumpPageInUIThread(PageDefine.PAGE_HUD_SET_SCREEN);
   }
   
   private void onClkResetControlPsw() {
	// TODO Auto-generated method stub
	   if(!BluetoothModel.getInstance().isConnected()){
		   ViewModel.getIns().showToast("设备未连接！");
		   return;
	   }
	   sendRequestSetPsw();
  }

void onPasswordEnter(String password){
	   Log.i("car", "onPasswordEnter "+password+"setting psw?"+mIsSettingPassword);
	   if(mIsSettingPassword){
		   onSettingPasswordEnter(password);
		   return;
	   }
	   if(mControllingItem == -1) return;
	   int item = -1; int action = -1;
	   switch(mControllingItem){
	   case R.id.car_window_close:
		   item = CMD_WINDOWS; action = OFF;
		   break;
	   case R.id.car_window_open:
		   item = CMD_WINDOWS; action = ON;
		   break;
	   case R.id.car_trunk_open:
		   item = CMD_TRUNK; action = ON;
		   break;
	   case R.id.car_power_off:
		   item = CMD_POWER; action = OFF;
		   break;
	   case R.id.car_power_on:
		   item = CMD_POWER; action = ON;
		   break;
	   case R.id.car_lock:
		   item = CMD_LOCK; action = OFF;
		   break;
	   case R.id.car_unlock:
		   item = CMD_LOCK; action = ON;
		   break;
	   case R.id.car_skylight_open:
		   item = CMD_SKYLIGHT; action = ON;
		   break;
	   }
//	   if(isCommandExcutable(item, action,strPsw))
	   Log.i("car", "send controlCmd: "+item+" action:"+action);
	   sendControlCmd(item,action,password);
	   mControllingItem = -1;   
   }
   private void onSettingPasswordEnter(String password) {
	// TODO Auto-generated method stub
	 mIsSettingPassword = false;
	 sendSetPassword(password);
  }

public void onClkCarControl(){
	   //test
//	  if(mIsCarControlSupport) {
////		  ViewModel.getIns().jumpPage(PageDefine.PAGE_CAR_CONTROL);
//		  ViewModel.getIns().refreshView(R.layout.layout_password_dialog);
//		  return;
//	  }
	   if(!BluetoothModel.getInstance().isConnected()){
		   CarModel.getInstance().showToastInUIThread("设备未连接！");
		   return;
	   }
		   
	   if(!isPasswordRestored()){
		   ViewModel.getIns().showAlertDialog("现在设置","以后再试", "		您尚未设定控制密码，请按照说明书方法设定！", new OnMyDlgActionListener() {
			
			@Override
			public void onPositive() {
				// TODO Auto-generated method stub
	            Log.i("dlg", "onPositive");
	            if(BluetoothModel.getInstance().isConnected()){
	                sendRequestSetPsw();
	            }else{
	            	CarModel.getInstance().showToastInUIThread("设备未连接！");
	            }
			}
			
			@Override
			public void onNegative() {
				// TODO Auto-generated method stub
				Log.i("dlg", "onNegative");
			}
			@Override
			public void onDismiss() {
				// TODO Auto-generated method stub
				
			}
		});
	   }else {//
		   ViewModel.getIns().jumpPage(PageDefine.PAGE_CAR_CONTROL);   
	   }
   }
   
   public void onRecvMsg(byte[] buf,int len){
	   Log.i(tag, "onRecv "+String.format("%02X ", buf[1]));
	   if(buf[0] == 0x06){//hud set message
		   onRecvHUDSetMsg(buf,len);
		   return;
	   }
	   
	   switch(buf[1]){
	   case (byte)0xE0:{
 		   int controlCmd = buf[2];
 		   int controlParam = buf[3];
 		   onCmdExcuteState(controlCmd,controlParam);
	   }break;
	   case (byte)0xE1:
		   if(buf[2] == 0)
		   onNewCmdAvalible();
		   break;
	   case (byte)0xE2:{
		   int controlCmd = buf[2];
		   int errCode = buf[3];
		   onExcuteCmdErr(controlCmd,errCode);
	   }break;
	   case (byte)0xA0:{
		   int pswVerifyResult = buf[2];
		   onPswVerifyResult(pswVerifyResult);
	   }break;
	   case (byte)0xA1:{
		   int canPswSet = buf[2];
		   onPswCanSet(canPswSet);
	   }break;
	   case (byte)0xA2:{
		   Log.i(tag, "onSet psw result");
		   int setPswResult = buf[2];
//		   char[] pswChar = new char[8];
//		   System.arraycopy(buf, 3, pswChar, 0, 8);
//		   
//		   String strPsw = String.valueOf(pswChar, 0, pswChar.length);
//		   Log.i(tag, "psw:"+strPsw);
		   onSetPswResult(setPswResult,"123456");
	   }break;
	   case (byte)0xA3:{
		   onNeedVerifyPsw();
	    }break;
	  }
   }
   
   void onRecvHUDSetMsg(byte[] buf,int len){
	   if(buf[1] == 0x00){
		   Log.d(tag, "onQuery button state");
		   makeHUDSetMsgAndSend();
	   }
	   else if ((buf[1]&0x0FF) == 0xAA) {
			int pcbVersion = buf[2]&0x0FF;
			int storageAD = ((buf[8]&0x0FF)<<8)+(buf[7]&0x0FF);
			int openAD = ((buf[12]&0x0FF)<<8)+(buf[11]&0x0FF);
			AppModel.getInstance().setAxelaHUDHardwareInfo(pcbVersion,storageAD,openAD);
	   }
	   else if ((buf[1]&0x0FF) == 0xAB) {
			int pcbVersion = buf[2]&0x0FF;
			int storageAD = ((buf[4]&0x0FF)<<8)+(buf[3]&0x0FF);
			int openAD = ((buf[6]&0x0FF)<<8)+(buf[5]&0x0FF);
			AppModel.getInstance().setAxelaHUDHardwareInfo(pcbVersion,storageAD,openAD);
	   }
   }
   private void onNeedVerifyPsw() {
	// TODO Auto-generated method stub
	 Log.i(tag, "onNeedVerifyPsw");
	 mIsCarControlSupport = true;
	 ViewModel.getIns().setViewVisible(R.id.reset_control_psw, 1);
	 ViewModel.getIns().refreshView(ViewDefine.VIEW_APPS_LIST);
	 
	 if(isPasswordRestored())
		 sendVerifyPsw(mPassword);
//	 else
//		 BluetoothModel.getInstance().disconnectBT();
  }

  private void onSetPswResult(int setPswResult,String password) {
	// TODO Auto-generated method stub
	   Log.i("car", "onSetPswResult:"+setPswResult+" psw:"+password); 	
	   if(setPswResult == 0){//succeed
		   storePassword(password);
		   ViewModel.getIns().jumpPage(PageDefine.PAGE_CAR_CONTROL);
	   }else {
		  //show toest that set password fail 
	   }
   }

  boolean isShowCantSetPswNow = false;
   private void onPswCanSet(int canPswSet) {
	// TODO Auto-generated method stub
	   Log.i("car", "onCanSetPassword:"+canPswSet);
	  if(canPswSet == 0){//can set password
		  mIsSettingPassword = true;
		   ViewModel.getIns().refreshView(R.layout.layout_password_dialog);   
	  }else if(canPswSet == 1){//can not set password now
		  if(isShowCantSetPswNow) return;
		  isShowCantSetPswNow = true;
		  ViewModel.getIns().showAlertDialog("重试", "取消", "		没有处于可设置密码状态", new OnMyDlgActionListener() {
				
				@Override
				public void onPositive() {
					// TODO Auto-generated method stub
					isShowCantSetPswNow = false;
					sendRequestSetPsw();
				}
				
				@Override
				public void onNegative() {
					// TODO Auto-generated method stub
					isShowCantSetPswNow = false;
				}
				@Override
				public void onDismiss() {
				// TODO Auto-generated method stub
				   isShowCantSetPswNow = false;
				}
			}); 
	  }
   }

   private void onPswVerifyResult(int pswVerifyResult) {
	// TODO Auto-generated method stub
	   Log.i("car", "onPswVerifyResult:"+pswVerifyResult);
	   mIsVerifySucceed = (pswVerifyResult==0)?true:false;
	   if(mIsVerifySucceed){
		   mIsCarControlSupport = true;
		   ViewModel.getIns().setViewVisible(R.id.reset_control_psw, 1);
		   ViewModel.getIns().refreshView(ViewDefine.VIEW_APPS_LIST);
	   }
   }

   private void onExcuteCmdErr(int controlCmd, int errCode) {
	// TODO Auto-generated method stub
	switch(errCode){
	case 0x00://
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "正在执行指令，请稍后再试");
		break;
	case 0x01:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "行驶中，不能打开后备箱");
		break;
	case 0x02:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "不支持远程打开后备箱");
		break;
	case 0x03:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "汽车已启动，无法远程启动");
		break;
	case 0x04:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "已远程启动两次，需要重新打火");
		break;
	case 0x05:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "此时不能远程熄火");
		break;
	case 0x06:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "请先熄火离车后再操作");
		break;
	case 0x07:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "控制密码错误");
		break;
	case 0x08:
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "密码错误次数太多，请在一个小时后再试");
		break;
	}
}

	private void onNewCmdAvalible() {
		// TODO Auto-generated method stub
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, "");
	}

	private void onCmdExcuteState(int controlCmd, int param) {
		// TODO Auto-generated method stub
		String strHint = "正在执行指令";
		switch(controlCmd){
		case CMD_POWER:
			if(param == 0x0) strHint = "正在熄火";
			else if(param == 0x1) strHint = "正在启动";
			break;
		case CMD_WINDOWS:
			if(param == 0x0) strHint = "正在关车窗";
			else if(param == 0x1) strHint = "正在开车窗";
			break;
		case CMD_SKYLIGHT:
			if(param == 0x0) strHint = "正在关天窗";
			else if(param == 0x1) strHint = "正在开天窗";
			break;
		case CMD_LOCK:
			if(param == 0x0) strHint = "正在锁车";
			else if(param == 0x1) strHint = "正在开锁";
			break;
		case CMD_TRUNK:
			if(param == 0x1) strHint = "正在开后备箱";
		   break;
		}
		ViewModel.getIns().setViewProperty(R.id.car_control_hint, strHint);	   	
	}

	void storePassword(String password){
		SharedPreferenceUtil util = new SharedPreferenceUtil(mContext);
		util.setPasswd(password);
	}
   boolean isPasswordRestored(){
	   SharedPreferenceUtil util = new SharedPreferenceUtil(mContext);
	   mPassword = util.getPasswd();
	   if(mPassword != null && !mPassword.isEmpty())
		   return true;
	   else return false;
   }
   
   void sendRequestSetPsw(){
	   byte[] buf = new byte[]{(byte)0xA1,0x00};
	   packAndSendMsg(buf, buf.length);
   }
   
   
   void sendControlCmd(int item,int action,String psw){
	   byte[] buf = new byte[10];
	   buf[0] = (byte)item;
	   buf[1] = (byte)action;
	   for(int i=0;i<6;i++){
		   buf[2+i] = (byte)psw.charAt(i);
	   }
	   packAndSendMsg(buf, buf.length);
   }
   void sendVerifyPsw(final String psw){
	   if(psw.length()<6) return;
	   byte[] buf = new byte[9];
	   buf[0] = (byte)0xA0;
	   for(int i=0;i<6;i++){
		   buf[1+i] = (byte)psw.charAt(i);
	   }
	   packAndSendMsg(buf, buf.length);
   }
   void sendSetPassword(String psw){
	   if(psw.length()<6) return;
	   byte[] buf = new byte[9];
	   buf[0] = (byte)0xA2;
	   for(int i=0;i<6;i++){
		   buf[1+i] = (byte)psw.charAt(i);
	   }
	   packAndSendMsg(buf, buf.length);
   }
   
   
   
   void sendSimulatorKey(int key){
	   byte[] buf = new byte[]{(byte)0xA1,(byte)key};
	   packHudMsgAndSend(buf, buf.length);
   }
   
   private void packAndSendMsg(byte[] message,int len){
	    byte[] szMsg = new byte[len + 5];
		szMsg[0] = (byte) 0xFF;
		szMsg[1] = (byte) 0x55;
		szMsg[2] = (byte) (len + 1);
		szMsg[3] = (byte) 0x05;
		System.arraycopy(message, 0, szMsg, 4, len);

		byte sum = 0;
		int s = 0;
		int i = 0;
		for (i = 2; i < len + 4; i++) {
			s += (szMsg[i] & 0xFF);
		}
		sum = (byte) (s & 0xFF);
		szMsg[len + 4] = sum;
		BluetoothModel.getInstance().sendMessage(szMsg);
   }

   private void packHudMsgAndSend(byte[] message,int len){
	    Log.d(tag, "send hud msg buf0:"+message[0]+" buf1:"+message[1]);
	    byte[] szMsg = new byte[len + 5];
		szMsg[0] = (byte) 0xFF;
		szMsg[1] = (byte) 0x55;
		szMsg[2] = (byte) (len + 1);
		szMsg[3] = (byte) 0x06;
		System.arraycopy(message, 0, szMsg, 4, len);

		byte sum = 0;
		int s = 0;
		int i = 0;
		for (i = 2; i < len + 4; i++) {
			s += (szMsg[i] & 0xFF);
		}
		sum = (byte) (s & 0xFF);
		szMsg[len + 4] = sum;
		BluetoothModel.getInstance().sendMessage(szMsg);
  } 
   
}
